/*
   Copyright (c) 2005 Lucas Mello Schnorr <schnorr@gmail.com>
   
   This file is part of DIMVisual.
   
   DIMVisual is free software; you can redistribute it and/or modify it under
   the terms of the GNU Lesser General Public License as published by the
   Free Software Foundation; either version 2 of the License, or (at your
   option) any later version.
   
   DIMVisual is distributed in the hope that it will be useful, but WITHOUT ANY
   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
   for more details.
   
   You should have received a copy of the GNU Lesser General Public License
   along with DIMVisual; if not, write to the Free Software Foundation, Inc.,
   59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
*/
#include "MPIRASTROConverter.h"

static AllToOne *gather;
static int size = -1;

@implementation MPIRASTROConverter (Gather)
- (id) convertEventGather: (MPIRASTROEvent *) event
{
	NSMutableArray *ret = nil;
	NSString *container;
	int type, i;

	if (gather == nil){
		gather = [[AllToOne alloc] init];
	}
//	if (allgather == nil){
//		allgather = [[NSMutableArray alloc] init];
//	}
//	if (allgatherv == nil){
//		allgatherv = [[NSMutableArray alloc] init];
//	}
	
	ret = [[NSMutableArray alloc] init];

	container = [provider identifierForEntity: 
		[NSArray arrayWithObjects: @"Machine", @"Thread", nil]
				ids:
		[NSArray arrayWithObjects: [event machine],[event thread],nil]];

	if (container == nil){
		[ret release];
		return nil;
	}
	
	int etype = atoi ([[event type] cString]);

	/* MPI_ALLGATHER_IN */
	if (etype == MPI_ALLGATHER_IN){
		NSString *sendcount = [event int32AtIndex: 0];
		NSString *size = [event int32AtIndex: 1];
		NSString *members = [event stringAtIndex: 0];

		NSLog (@"ALL_GATHER_IN %@", container);
		for (i = 0; i < [size intValue]; i++){
//			NSLog (@"%d: entering %@(%@), root %@",i, container, [event time],[NSString stringWithFormat:@"%d",i]);
			[gather memberEntering: container
				andEventNode: [event node]
				andEventTime: [event time]
				andRootNode: [NSString stringWithFormat:@"%d",i]
				andCommSize: size
				andMembersId: members];
		}
		[ret addObject: [self addPajeSetState: @"MPI_ALLGATHER" time: [event time] container: container]];

	/* MPI_ALLGATHER_OUT */
	}else if (etype == MPI_ALLGATHER_OUT){
		NSString *recvcount = [event int32AtIndex: 0];
		NSString *size = [event int32AtIndex: 1];
		NSString *members = [event stringAtIndex: 0];
	
		NSLog (@"ALL_GATHER_OUT %@", container);
		for (i = 0; i < [size intValue]; i++){
//			NSLog (@"%d: exiting %@(%@), root %@", i, container, [event time], [NSString stringWithFormat:@"%d",i]);
			[ret addObjectsFromArray:
				[gather memberExiting: container 
					andEventTime: [event time] 
					andOperationName: @"allgather"
					andRootNode: [NSString stringWithFormat:@"%d",i]
					andMembersId: members
					andProvider: provider]];
		}
		[ret addObject: [self addPajeSetState: @"running" time: [event time] container: container]];

	/* MPI_ALLGATHERV_IN */
	}else if (etype == MPI_ALLGATHERV_IN){
		[ret addObject: [self addPajeSetState: @"MPI_ALLGATHERV" time: [event time] container: container]];

	/* MPI_ALLGATHERV_OUT */
	}else if (etype == MPI_ALLGATHERV_OUT){
		[ret addObject: [self addPajeSetState: @"running" time: [event time] container: container]];

	/* MPI_GATHER_IN */
	}else if (etype == MPI_GATHER_IN){
		NSString *sendcnt = [event int32AtIndex: 0];
		NSString *size = [event int32AtIndex: 1];
		NSString *root = [event int32AtIndex: 2];
		NSString *members = [event stringAtIndex: 0];
		
		[gather memberEntering: container
			andEventNode: [event node]
			andEventTime: [event time]
			andRootNode: root
			andCommSize: size
			andMembersId: members];
		[ret addObject: [self addPajeSetState: @"MPI_GATHER" time: [event time] container: container]];

	/* MPI_GATHER_OUT */
	}else if (etype == MPI_GATHER_OUT){
		NSString *recvcount = [event int32AtIndex: 0];
		NSString *root = [event int32AtIndex: 1];
		NSString *members = [event stringAtIndex: 0];
		
		[ret addObjectsFromArray: [gather memberExiting: container
			andEventTime: [event time]
			andOperationName: @"gather"
			andRootNode: root
			andMembersId: members
			andProvider: provider]];
		[ret addObject: [self addPajeSetState: @"running" time: [event time] container: container]];

	/* MPI_GATHERV_IN */
	}else if (etype == MPI_GATHERV_IN){
		NSString *sendcnt = [event int32AtIndex: 0];
		NSString *size = [event int32AtIndex: 1];
		NSString *root = [event int32AtIndex: 2];
		NSString *members = [event stringAtIndex: 0];

		[gather memberEntering: container
			andEventNode: [event node]
			andEventTime: [event time]
			andRootNode: root
			andCommSize: size
			andMembersId: members];
		[ret addObject: [self addPajeSetState: @"MPI_GATHER" time: [event time] container: container]];

	/* MPI_GATHERV_OUT */
	}else if (etype == MPI_GATHERV_OUT){
		NSString *root = [event int32AtIndex: 0];
		NSString *members = [event stringAtIndex: 0];

		[ret addObjectsFromArray: [gather memberExiting: container
			andEventTime: [event time]
			andOperationName: @"gatherv"
			andRootNode: root
			andMembersId: members
			andProvider: provider]];
		[ret addObject: [self addPajeSetState: @"running" time: [event time] container: container]];
	}
	[ret autorelease];
	return ret;
}
@end
